home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d1 / ax1k.arc / AX.C next >
Text File  |  1989-02-11  |  7KB  |  242 lines

  1. #include <dos.h>
  2. #include <io.h>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6.  
  7. #define MAX_FILEMEM 2300
  8. #define MAX_DOS_LINE 128
  9.  
  10. /* recommended linker parameters: /st:0x80ff /se:28 /cp:1 */
  11.  
  12. main(argc, argv)
  13. int argc;
  14. char *argv[];
  15. {
  16.     struct find_t filespec;        /* MS C file data structure */ 
  17.     int filecount = 0;        /* number of files found */
  18.     int i = 0;            /* general purpose integer */
  19.     int pathlen;            /* length of path part of file spec */
  20.     char vidout[81];        /* strings to be displayed on screen */
  21.     char del_ans;            /* answer to "Delete these files?" */
  22.     char fil_ans;            /* answer to "Delete this file?" */
  23.     char fullname[MAX_DOS_LINE];    /* complete file spec */
  24.     char path[MAX_DOS_LINE];    /* path of file spec + some filename */
  25.     unsigned long bytes = 0;    /* total size of matching files */
  26.     char flist[MAX_FILEMEM][14];    /* place to remember filenames */
  27.  
  28.     /* make sure there is one and only one command line argument to ax */
  29.     if (argc != 2) {
  30.         say("\nAx deleter version 1k\nby D. David Kaufman\n\n");
  31.         say("syntax: ax <filespec>\n");
  32.         return;
  33.     }
  34.  
  35.     strcpy(fullname, argv[1]);    /* store file spec in fullname */
  36.     i = (strlen(fullname) - 1);    /* see if adding *.* or \*.* needed */
  37.     if (fullname[i] == '.') {
  38.         /* special handling for filespecs ending with dot */
  39.         strcat(fullname, "\\*.*");
  40.     } else if ((fullname[i] == '\\') || (fullname[i] == ':')) {
  41.         /* special handling for filespecs ending with \ or : */
  42.         strcat(fullname, "*.*");
  43.     }
  44.     if (_dos_findfirst(fullname, _A_NORMAL, &filespec)) {
  45.         /* no files match the spec, but maybe a subdir does */
  46.         if (_dos_findfirst(fullname, _A_SUBDIR, &filespec) == 0) {
  47.             /* yes, it's a subdir */
  48.             /* convert to a complete filespec by adding \*.*  */
  49.             strcat(fullname, "\\*.*");
  50.             /* then repeat test for matching files */
  51.             if (_dos_findfirst(fullname, _A_NORMAL, &filespec)) {
  52.                 /* still no matches, so gripe and exit */
  53.                 nomatch();
  54.                 return;
  55.             }
  56.         } else {
  57.             /* no files, no subdir, so gripe and exit */
  58.             nomatch();
  59.             return;
  60.         }
  61.     }
  62.     say("\n");
  63.     dispname(filespec.name);    /* display filename */
  64.     bytes = bytes + (unsigned long)filespec.size;    /* add size to total */
  65.     strcpy(flist[filecount++], filespec.name);    /* remember filename */
  66.     while (_dos_findnext(&filespec) == 0) {
  67.         /* and repeat until no more files found */
  68.         dispname(filespec.name);    
  69.         bytes = bytes + (unsigned long)filespec.size;
  70.         if (filecount < MAX_FILEMEM) {
  71.             /* still room in array to remember filename */
  72.             strcpy(flist[filecount++], filespec.name);
  73.         } else {
  74.             /* oh well, too many names to remember anyway */
  75.             filecount++;
  76.         }
  77.     }
  78.  
  79.     /* at end of showing files, display an extra line */
  80.     /* unless we already wrapped from stopping at column 80 */ 
  81.     if ((filecount % 5) !=0) {
  82.         say("\n\n");
  83.     } else {
  84.         say("\n");
  85.     }
  86.  
  87.     /* say how many bytes the files add up to */
  88.     outcomma(ultoa(bytes, vidout, 10));
  89.     if (bytes != 1) {
  90.         say(" bytes in ");
  91.     } else {
  92.         say(" byte in ");
  93.     }
  94.  
  95.     /* and how many files were found, and prompt user about deleting */
  96.     if (filecount == 1) {
  97.         say("1 file.  Delete? (yes/NO) ");
  98.     } else {
  99.         itoa(filecount, vidout, 10);
  100.         outcomma(vidout);
  101.         say(" files.  Delete? (yes/NO/prompt) ");
  102.     }
  103.     del_ans = (getch() | 32);
  104.  
  105.     if (del_ans == 'p') {
  106.         /* user selected prompt mode */
  107.         if (filecount == 1) {
  108.             /* but we don't do prompt mode for just one file */
  109.             del_ans = 'n';
  110.         } else {
  111.             say("Prompt\n\n");
  112.         }
  113.     } else if (del_ans == 'y') {
  114.         /* user said yes to delete */
  115.         say("Yes\n");;
  116.      }
  117.     if ((del_ans == 'p') || (del_ans == 'y')) {    
  118.         /* user wants to delete (either prompted or not) */
  119.         /* now figure out path component of fullname */
  120.         strcpy(path, fullname);    /* copy path from fullname */
  121.         i = strlen(path);
  122.         while ((path[i] != '\\') && (path[i] != ':') && (i >= 0)) {
  123.             /* chop path at rightmost colon or backslash */
  124.             path[i--] = 0;
  125.         }
  126.  
  127.         /* path now contains only the path data from fullname.
  128.          * filenames are tacked on to the end of the path and passed 
  129.          * to the eatfile routine, which can only eat one file at a 
  130.          * time.  each new filename overwrites the old filename in the
  131.          * path string, which is why we bother to note the length of 
  132.          * the actual path component */
  133.         pathlen = strlen(path);    
  134.  
  135.         if (filecount <= MAX_FILEMEM) {
  136.             /* delete using list in memory if not too many files */
  137.             for (i = 0; i < filecount; i++) {
  138.                 eatfile(path, pathlen, flist[i], del_ans);
  139.             }
  140.         } else {
  141.             /* otherwise, delete by getting the names from disk */
  142.             _dos_findfirst(fullname, _A_NORMAL, &filespec);
  143.             eatfile(path, pathlen, filespec.name, del_ans);
  144.             while (_dos_findnext(&filespec) == 0) {
  145.                 eatfile(path, pathlen, filespec.name, del_ans);
  146.             }
  147.         }
  148.     } else {
  149.         /* user said no to deleting the files, so just echo and exit */
  150.         say("No\n");
  151.     }
  152. }
  153.  
  154.  
  155. say(vidout)    /* this routine just displays a string */
  156. char vidout[];    /* (printf comes with a lot of unnecessary code) */
  157. {
  158.     int i = 0;
  159.     while (vidout[i]) {
  160.         if (vidout[i] == '\n') {
  161.             putch(13);
  162.         }
  163.         putch(vidout[i++]);
  164.     }
  165. }
  166.  
  167.  
  168. nodel(path)    /* routine to inform user that delete request failed */
  169. char path[];
  170. {
  171.     say("\nDOS won't erase ");
  172.     say(path);
  173. }
  174.  
  175.  
  176. dispname(filename)    /* routine to display a filename in 16-byte field */
  177. char filename[13];
  178. {
  179.     int i;
  180.  
  181.     say(filename);
  182.     i = strlen(filename);
  183.     while (i++ < 16) {
  184.         putch(' ');
  185.     }
  186. }
  187.  
  188.  
  189. nomatch()    /* routine to inform user that no files matched the spec */
  190. {
  191.     say("\nNo files match.\n");
  192. }
  193.  
  194.  
  195. eatfile(path, pathlen, filename, del_ans)    /* delete a file */
  196. char path[];
  197. int pathlen;
  198. char filename[];
  199. char del_ans;
  200. {
  201.     char fil_ans;
  202.  
  203.     strcpy(&path[pathlen], filename);    /* overwrite old filename */
  204.     if (del_ans == 'p') {
  205.         /* we are in prompt mode, so prompt for each deletion */
  206.         dispname(filename);    
  207.         say("Delete? (yes/NO) ");
  208.         fil_ans = (getch() | 32);
  209.         if (fil_ans == 'y') {
  210.             say("Yes\n");;
  211.             if (remove(path) == -1) {    /* delete it, or */
  212.                 nodel(path);    /* gripe if attempt failed */
  213.             }
  214.         } else {
  215.             say("No\n");
  216.         }
  217.     } else if (remove(path) == -1) {    /* prompt mode off, just ax */
  218.         nodel(path);            /* gripe if attempt failed */
  219.     }
  220. }
  221.  
  222.  
  223. outcomma(string)    /* display a numeric string in nice comma format */
  224. char string[];
  225. {
  226.     int i, length;
  227.  
  228.     length = strlen(string);
  229.     for (i = 0; i < length; i++) {
  230.         /* dividing an int by 3 will cause significant bits to
  231.          * be lost unless it was a multiple of 3 already. 
  232.          * we multiply by 3 and see if we got what we started
  233.          * with.  if so, then a comma should be displayed before
  234.          * the digit in this position (except when no digit has been
  235.          * displayed at all yet) */
  236.         if (((((length - i) / 3) * 3) == (length - i)) && (i > 0)) {
  237.             putch(',');    /* time to print a comma */
  238.         }
  239.         putch(string[i]);    /* print the digit */
  240.     }
  241. }
  242.